
#include	"SysConfig.h"
#include	"Define.h"
#include	"Port.h"
#include	"Model_Option.h"
#include	"Function.h"
#include	"Display.h"
#include	"Audio.h"
#ifdef  HERO
#include	"Hero_Drv.h"
#endif
#ifdef  LC786XXX
#include "LC786XXX.h"
#endif
#ifdef  ST7565P
#include	"ST7565P.h"
#endif

#ifdef  MIC
#include	"MIC.h"
#endif

#ifdef  AUTO_GUIDE
#include	"AutoGuide.h"
#endif

#ifdef  AV_CONTROLLER
#include	"AVController.h"

#define	AVC_MANUAL_COM
#if  0
#define	AVC_CLK		p7_7
#define	AVC_CLK_D	pd7_7
#define	AVC_DATA	p8_0
#define	AVC_DATA_D	pd8_0
#else
#define	AVC_CLK		p8_0//p7_7
#define	AVC_CLK_D	pd8_0//pd7_7
#define	AVC_DATA	p7_7//p8_0
#define	AVC_DATA_D	pd7_7//pd8_0
#endif

#define	AVC_COMMAND_BUFFER_SIZE	16
#define	AVC_DATA_WRITE		0xAA
#define	AVC_DATA_READ		0x55
#define	AVC_DATA_CHECKSUM	0xA5
unsigned char ucAVC_KeyCommand[AVC_COMMAND_BUFFER_SIZE];
unsigned char ucAVC_KeyCmd_wPtr;
unsigned char ucAVC_KeyCmd_sPtr;

unsigned char ucAVC_TX_Buf[4];
unsigned char ucAVC_RX_Buf[4];
unsigned char ucAVC_RX_Cnt;

unsigned char ucAVC_RX_Compelete;

unsigned char ucAVC_Process;
#define	AVC_PRS_IDLE		0
#define	AVC_PRS_NORMAL		1
#define	AVC_PRS_WORK		2
unsigned short ucAVC_Process_Timer5msec;

AVC_MODE ucAVC_Mode;
AVC_DRIVER_MODE	ucAVC_DriverSpeakerMode;
AVC_PS_STATUS	ucAVC_Selector;
AVC_MIC_STATUS ucAVC_MicStatus;

extern unsigned char ucAUDIO_Fader;
extern unsigned char ucDECK_Disc;
extern unsigned char FUNC_CheckFunctionAvailable(UI_FUNCTION ucFunc);

AVC_MODE AVC_GetMode(void)
{
	return(ucAVC_Mode);
}

void AVC_SetMode(AVC_MODE ucMode)
{
	ucAVC_Mode = ucMode;
}

AVC_DRIVER_MODE AVC_GetDriverSpeakerMode(void)
{
	return(ucAVC_DriverSpeakerMode);
}

void AVC_SetDriverSpeakerMode(AVC_DRIVER_MODE ucMode)
{
	ucAVC_DriverSpeakerMode = ucMode;
}

AVC_PS_STATUS AVC_GetPS_Status(void)
{
	return(ucAVC_Selector);
}

void AVC_SetPS_Status(AVC_PS_STATUS ucMode)
{
	ucAVC_Selector = ucMode;
}

AVC_MIC_STATUS AVC_GetMicStatus(void)
{
	return(ucAVC_MicStatus);
}

void AVC_SetMicStatus(AVC_MIC_STATUS ucMode)
{
	ucAVC_MicStatus = ucMode;
}

void AVC_SetKeyCommand(unsigned char ucCmd)
{
	if  (OPT_GetOption(OPT_MASK_AVC) == 0)
	{
		return;
	}
	ucAVC_KeyCommand[ucAVC_KeyCmd_wPtr] = ucCmd;
	ucAVC_KeyCmd_wPtr = (++ucAVC_KeyCmd_wPtr) % AVC_COMMAND_BUFFER_SIZE;
	ucAVC_Process_Timer5msec = 0;//500/5;
}

unsigned char AVC_GetKeyCommand(void)
{
	unsigned char ucCmd;

	ucCmd = ucAVC_KeyCommand[ucAVC_KeyCmd_sPtr];
	ucAVC_KeyCmd_sPtr = (++ucAVC_KeyCmd_sPtr) % AVC_COMMAND_BUFFER_SIZE;

	return(ucCmd);
}

void AVC_RX_Interrupt(void)
{
	unsigned char ucData;

	ucData = u5rb;
	
	if  (ucAVC_TX_Buf[0] == AVC_DATA_READ)
	{
		ucAVC_RX_Buf[ucAVC_RX_Cnt] = ucData;
		if  (++ucAVC_RX_Cnt > 2)
		{
			s5ric = 0x00;
			re_u5c1 = 0;
			ucAVC_RX_Compelete = 1;
		}
		else
		{
			u5tb = 0x00;
		}
	}
}

void AVC_TX_Interrupt(void)
{
	if  (ucAVC_TX_Buf[0] == AVC_DATA_WRITE)
	{
		if  (ucAVC_RX_Cnt == 0)
		{			
			ucAVC_RX_Cnt = 1;
			u5tb = ucAVC_TX_Buf[ucAVC_RX_Cnt];
		}
		else
		{
			s5tic = 0x00;
			te_u5c1 = 0;
		}
	}
	
	if  (ucAVC_TX_Buf[0] == AVC_DATA_READ)
	{
		s5tic = 0x00;
	//	te_u5c1 = 0;
		AVC_SerialReadStart();
	}
#if 0
	if  (ucAVC_TX_Buf[0] == AVC_DATA_READ)
	{
		// if  (ucAG_RX_Cnt > 2)	
		//	serial end;
		//	ucAG_RX_Compelete = 1;
		// else
		//  TX = 0xFF;
		//  ucAG_RX_Buf[ucAG_RX_Cnt] = RX;
		//  ++ucAG_RX_Cnt;
	}
	else
	{
		// if  (ucAG_RX_Cnt > 0)	serial end;
		// TX = ucAG_TX_Buf[1];
		// ++ucAG_RX_Cnt;
	}
#endif
}

void AVC_SerialSendStart(unsigned char ucData)
{
	ucAVC_RX_Cnt = 0;
	nch_u5c0 = 0;
	s5tic = 0x00;
	s5ric = 0x00;
	u5tb = ucData;
	s5tic = 0x05;	// Interrupt enable & Level Set 5
	te_u5c1 = 1;
}

void AVC_SerialReadStart(void)
{
	nch_u5c0 = 1;
	ucAVC_RX_Cnt = 0;
	u5tb = 0x00;
	s5ric = 0x05;
	re_u5c1 = 1;
}

void AVC_SetSerial(void)
{
#ifndef  AVC_MANUAL_COM
#ifdef  M16C_64G

	u5mr = 0x01;	// Serial I/O mode select bit[0,1,2] : (001) Clock synchronous serial I/O mode
	u5c0 = 0x92;//0x99; // UiBRG count source select bit [0,1] : (01) f8SIO is selected
					// Transmit register empty flag[3] : (1) No data present in transmit register(transmission completed)
					// Transfer format select bit[7] : (1) MSB First
	u5brg = 100;
	u5c1 = 0x10;//0x10;
	u5smr2 = 0x00;
	u5smr3 = 0x00;
	u5smr4 = 0x00;

#endif
#endif
}

void AVC_PS_SourcePlay(void)
{
	if	((OPT_GetOption(OPT_MASK_CD)) && (FUNC_CheckFunctionAvailable(FUNC_CD)== 1))
	{
		LC786XXX_ChangeToCD();
	}
	else
	{
		if	(FUNC_CheckFunctionAvailable(FUNC_USB) == 1)
		{
			LC786XXX_ChangeToUSB();
		}
	}
}

void AVC_RX_ProcessMain(void)
{
	if  (ucAVC_RX_Compelete == 0)
	{
		return;
	}
	ucAVC_RX_Compelete = 0;
	if  (ucAVC_RX_Buf[2] != AVC_DATA_CHECKSUM)
	{
		return;
	}
	if  ((ucAVC_RX_Buf[0] + ucAVC_RX_Buf[1]) != 0xFF)
	{
		return;
	}

	switch  (ucAVC_RX_Buf[0])
	{
		case AVC_RX_RMC_VOL_UP:
			break;
		case AVC_RX_RMC_VOL_DOWN:
			break;
	// ................ Need Add More	
		case AVC_RX_MODE1:
		case AVC_RX_MODE2:
		case AVC_RX_MODE3:
		case AVC_RX_MODE4:
			if  ((ucAVC_RX_Buf[0] - 5) != AVC_GetMode())
			{
				AVC_SetMode(ucAVC_RX_Buf[0] - 5);
				DISP_ClearTempDisplayMode();
				MENU_Clear();
			}
			if  (FUNC_GetCurrentFunction() != FUNC_AVC_MODE)
			{
				DISP_ClearTempDisplayMode();
				MENU_Clear();
				if  (FUNC_PowerStatus() == 1)
				{
					FUNC_FunctionChangeStart(FUNC_AVC_MODE,FUNC_CHANGE_SEQ0);
				}
				else
				{
					FUNC_SaveCurrentFunction(FUNC_AVC_MODE);
				}
				
		//		AVC_SetKeyCommand(AVC_KEY_RETURN_0x00FF);
			}
			break;
		case AVC_RX_MODE_OFF:
			if  (FUNC_GetCurrentFunction() == FUNC_AVC_MODE)
			{
				AVC_SetMode(AVC_MODE_OFF);
				DISP_ClearTempDisplayMode();
				MENU_Clear();
				
				if  (FUNC_PowerStatus() == 1)
				{
					FUNC_FunctionChangeStart(FUNC_GetPreviousFunction(),FUNC_CHANGE_SEQ0);
				}
				else
				{
					FUNC_SaveCurrentFunction(FUNC_GetPreviousFunction());
				}
			}
			break;
		case AVC_RX_DRV_ON:
			if  (AVC_GetDriverSpeakerMode() != AVC_DRV_ON)
			{
				AVC_SetDriverSpeakerMode(AVC_DRV_ON);
				
		//		HERO_SetFader(ucAUDIO_Fader);
				HERO_SetFader(FADER_DEFAULT);
		//		AUDIO_SetSpeaker();
				
				if  (FUNC_PowerStatus() == 1)
				{
					MENU_Clear();
					DISP_SetTempDisplayMode(DISP_DRV_ON);
				}
			}
			break;
		case AVC_RX_DRV_OFF:
			if  (AVC_GetDriverSpeakerMode() != AVC_DRV_OFF)
			{
				AVC_SetDriverSpeakerMode(AVC_DRV_OFF);
				
		//		HERO_SetFader(FADER_DEFAULT);
				HERO_SetFader(ucAUDIO_Fader);
		//		AUDIO_SetSpeaker();
				
				if  (FUNC_PowerStatus() == 1)
				{
					MENU_Clear();
					DISP_SetTempDisplayMode(DISP_DRV_OFF);
				}
			}
			break;
		case AVC_RX_PS_ON:
			if  (AVC_GetPS_Status() == AVC_PS_OFF)
			{
				AVC_SetPS_Status(AVC_PS_ON);
				
				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_SP_ON);

				AVC_PS_SourcePlay();
			}
			break;
		case AVC_RX_PS_OFF:
			if  (AVC_GetPS_Status() == AVC_PS_ON)
			{
				AVC_SetPS_Status(AVC_PS_OFF);
				
				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_SP_OFF);

				switch  (FUNC_GetCurrentFunction())
				{
					case FUNC_USB:
				#ifdef  CD
					case FUNC_CD:
				#endif
						break;
					default:
						LC786XXX_GoToSleep();
						break;
				}
			}
			break;
		case AVC_RX_MIC_OFF:
			if  (AVC_GetMicStatus() != AVC_MIC_OFF)
			{
				AVC_SetMicStatus(AVC_MIC_OFF);
				
				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_AVC_MIC_OFF);
				
		//		if  (MIC_GetMicStatus() == MIC_ON)
		//		{
		//			MIC_SetMicStatus(MIC_OFF);
		//			MIC_SetMixMode(MIX_ON);
		//		}
				
			}
			break;
		case AVC_RX_MIC1_ON:
		case AVC_RX_MIC2_ON:
			if  (AVC_GetMicStatus() != AVC_MIC_ON)
			{
				AVC_SetMicStatus(AVC_MIC_ON);
				
				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_AVC_MIC_ON);
			}
			break;
		case AVC_RX_MIC_ON:
			if  (AVC_GetMicStatus() != AVC_MIC_ON)
			{
				AVC_SetMicStatus(AVC_MIC_ON);
				
				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_AVC_MIC_ON);

		//		if  (MIC_GetMicStatus() == MIC_OFF)
		//		{
		//			MIC_SetMicStatus(MIC_ON);
		//			MIC_SetMixMode(MIX_OFF);
		//		}
			}
			break;
		case AVC_RX_MIX_ON:
			if  (AVC_GetMicStatus() != AVC_MIX_ON)
			{
				AVC_SetMicStatus(AVC_MIX_ON);

				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_AVC_MIX_ON);

			//	MIC_SetMixMode(MIX_ON);
			//	if  (MIC_GetMicStatus() == MIC_OFF)
			//	{
			//		MIC_SetMicStatus(MIC_ON);
			//	}
			}
			break;
		case AVC_RX_MIX_OFF:
			if  (AVC_GetMicStatus() != AVC_MIX_OFF)
			{
				AVC_SetMicStatus(AVC_MIX_OFF);
				
				MENU_Clear();
				DISP_SetTempDisplayMode(DISP_AVC_MIX_OFF);
			}
			break;
		default:
			M_NOP;
			break;
	}
}

void AVC_Delay(unsigned short ucTime)
{
	unsigned short i;

	for(i = 0; i < ucTime; ++i)
	{
		M_NOP;
		M_NOP;
		M_NOP;
		M_NOP;
		M_NOP;
		M_NOP;
		M_NOP;
		M_NOP;
		M_NOP;		
		M_NOP;
		M_NOP;
		M_NOP;
	}
}

void AVC_WriteData(unsigned char ucData)
{
	unsigned char i;
		
	for(i = 0; i < 8; ++i)
	{
		AVC_CLK = 0;
		if  (ucData & 0x80)
		{
			AVC_DATA = 1;
		}
		else
		{
			AVC_DATA = 0;
		}
		ucData = (ucData << 1) & 0xFE;
		AVC_Delay(90);
		AVC_CLK = 1;
		AVC_Delay(140);
	}
//	AVC_Delay(100);
}

unsigned char AVC_ReadData(void)
{
	unsigned char i;
	unsigned char ucData = 0;	
	
	for(i = 0; i < 8; ++i)
	{
		AVC_CLK = 0;
		AVC_Delay(100);
		AVC_CLK = 1;
		AVC_Delay(100);

		ucData = (ucData << 1) & 0xFE;
		if  (AVC_DATA == 1)
		{
			ucData = ucData | 0x01;
		}
	}	
	
	return(ucData);
}

void AVC_Manual_Read(void)
{
	unsigned char i;
	unsigned char ucData;
	
	AVC_DATA_D = 1;
	AVC_WriteData(AVC_DATA_READ);
		
	AVC_Delay(50);
	AVC_DATA_D = 0;

	ucAVC_RX_Buf[0] = AVC_ReadData();
	AVC_Delay(50);
	ucAVC_RX_Buf[1] = AVC_ReadData();
	AVC_Delay(50);
	ucAVC_RX_Buf[2] = AVC_ReadData();
	ucAVC_RX_Compelete = 1;

//	AVC_DATA_D = 0;
//	AVC_CLK_D = 0;
}

void AVC_Manual_Write(void)
{
	unsigned char i;
	unsigned char ucData;
	
	AVC_DATA_D = 1;
	AVC_WriteData(AVC_DATA_WRITE);
	AVC_Delay(50);
	AVC_WriteData(ucAVC_TX_Buf[1]);
	
//	AVC_CLK_D = 0;
}

void AVC_CommunicationMain(void)
{
	memset(&ucAVC_TX_Buf[0], 0x00, 4);
	memset(&ucAVC_RX_Buf[0], 0x00, 4);
	if  (ucAVC_KeyCmd_sPtr == ucAVC_KeyCmd_wPtr)
	{
		ucAVC_TX_Buf[0] = AVC_DATA_READ;	// Read 4Byte = (Send 0x55) + (Read 3Byte)
	#ifdef  AVC_MANUAL_COM
		AVC_Manual_Read();
	#else
		AVC_SerialSendStart(ucAVC_TX_Buf[0]);
	#endif
	}
	else
	{
		ucAVC_TX_Buf[0] = AVC_DATA_WRITE;	// Write = (Send 0xAA) + (Send 1Byte)
		ucAVC_TX_Buf[1] = AVC_GetKeyCommand();
	#ifdef  AVC_MANUAL_COM
		AVC_Manual_Write();
	#else
		AVC_SerialSendStart(ucAVC_TX_Buf[0]);
	#endif
	}
}

void AVC_ProcessStart(void)
{
#ifdef	AVC_MANUAL_COM
	AVC_CLK_D = 1;
	AVC_DATA_D = 1;
	AVC_CLK = 1;
	AVC_DATA = 1;
#endif
	pd7_6 = 0;
	ucAVC_Process = AVC_PRS_NORMAL;
	ucAVC_Process_Timer5msec = 1000/5;
	PO_AVC_RST = 1;
	AVC_SetSerial();
}

void AVC_ProcessStop(void)
{
//	AVC_SetPS_Status(AVC_PS_OFF);
	AVC_SetMicStatus(AVC_MIC_OFF);
//	AVC_SetMode(AVC_MODE_OFF);
//	AVC_SetDriverSpeakerMode(AVC_DRV_NONE);

	ucAVC_Process = AVC_PRS_IDLE;
	ucAVC_Process_Timer5msec = 0;
	PO_AVC_RST = 0;
#ifdef  M16C_64G
	u5mr = 0x00;
#endif
}

void AVC_Main(void)
{	
	if  (OPT_GetOption(OPT_MASK_AVC) == 0)
	{
		return;
	}
	if  (ucAVC_Process_Timer5msec != 0)
	{
		return;
	}

	switch  (ucAVC_Process)
	{
		case AVC_PRS_IDLE:
			break;
		case AVC_PRS_NORMAL:
			ucAVC_Process = AVC_PRS_WORK;
			break;
		case AVC_PRS_WORK:
			AVC_CommunicationMain();
			ucAVC_Process_Timer5msec = 100/5;
			break;
	}
}

void AVC_MODE_DISP_MainText(void)
{
	unsigned char ucBuf[9];
	
#ifdef  MIC
	if	(MIC_GetMicStatus() == MIC_ON)
	{
		MIC_DISP_MainText();
		return;
	}
#endif

	memset(&ucBuf[0], 0x00, 9);
	memcpy(&ucBuf[0], "MODE ", 5);

	switch  (AVC_GetMode())
	{
		case AVC_MODE1:
			ucBuf[5] = '1';
			break;
		case AVC_MODE2:
			ucBuf[5] = '2';
			break;
		case AVC_MODE3:
			ucBuf[5] = '3';
			break;
		case AVC_MODE4:
			ucBuf[5] = '4';
			break;
	}
#ifdef  ST7565P
	ST7565_UpdateDisplayString(13, &ucBuf[0], 1);
#endif
}

void AVC_MODE_DISP_SubText(void)
{
	unsigned char ucBuf[5];

	memset(&ucBuf[0], 0x00, 5);
	memcpy(&ucBuf[0], "MD", 2);
	switch  (AVC_GetMode())
	{
		case AVC_MODE1:
			ucBuf[2] = '1';
			break;
		case AVC_MODE2:
			ucBuf[2] = '2';
			break;
		case AVC_MODE3:
			ucBuf[2] = '3';
			break;
		case AVC_MODE4:
			ucBuf[2] = '4';
			break;
	}
#ifdef  ST7565P
	ST7565_UpdateSubDisplayData(&ucBuf[0]);
#endif
}

void AVC_MODE_DISP_IconMain(void)
{
}

#endif

